package org.plants.algo;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Vector;

import org.plants.additional_info.Pair;

public class BestCoverOscilator {
	public static int MIN_TURNS = 7;
	public static double TOLERANCE = 70.0;
	public static double UPPER_TOLERANCE = 140.0;
	public static int PLANTS_NUM = 28;
	public static Pair SPACE_DIM = new Pair(14, 14);
	public static int PRIORITY = 8;
	
	private static int getFiguresAtLine(int poolSize) {
		return poolSize / SPACE_DIM.getFirst();
	}
	private static int getFiguresAtRaw(int poolSize) {
		return poolSize / SPACE_DIM.getSecond();
	}
	private static void initializePlantMap(Map<Integer, Vector<Integer>> map) {
		for (Integer i = 0; i < SPACE_DIM.getSecond(); i++) {
			Vector<Integer> temp = new Vector<Integer>();
			switch (i) {
			case 2: 
				temp.add(4); temp.add(7); temp.add(9);
				map.put(i, temp);
				break;
			case 3:
				temp.add(2); temp.add(3); temp.add(5); temp.add(7); temp.add(8); temp.add(9);
				map.put(i, temp);
				break;
			case 4:
				temp.add(3); temp.add(10);
				map.put(i, temp);
				break;
			case 5:
				temp.add(2); temp.add(3); temp.add(9);
				map.put(i, temp);
				break;
			case 7:
				temp.add(3); temp.add(9); temp.add(10);
				map.put(i, temp);
				break;
			case 8:
				temp.add(2); temp.add(9);
				map.put(i, temp);
				break;
			case 9:
				temp.add(3); temp.add(4); temp.add(5); temp.add(7); temp.add(9); temp.add(10);
				map.put(i, temp);
				break;
			case 10:
				temp.add(3); temp.add(5); temp.add(8);
				map.put(i, temp);
				break;
			default:
				map.put(i, new Vector<Integer>());
				break;
			}
	
		}
	}
	
	public static String getName() {
		return "BestCoverOscilator";
	}
	
	public static boolean isSuitableFigure(int inputPlantsNumber, int poolSize, int lifeDuration) {
		if (lifeDuration >= MIN_TURNS) {
			int optimum = (getFiguresAtLine(poolSize)*getFiguresAtRaw(poolSize)) * PLANTS_NUM;
			if ((((TOLERANCE / 100) * optimum) < inputPlantsNumber) &&
					(inputPlantsNumber <= (UPPER_TOLERANCE / 100) * optimum))
				return true;
		}
		return false;
	}
	
	public static void fillPool(Character[][] pool, int inputPlantsNumber, int poolSize) {
		int availablePlants = ((inputPlantsNumber / PLANTS_NUM) * PLANTS_NUM);
		
		//Fill the figures!
		int columnNumber = 0;
		Map<Integer, Vector<Integer>> plantMap = new HashMap<Integer, Vector<Integer>>();
		initializePlantMap(plantMap);
		
		while (availablePlants > 0 && columnNumber < getFiguresAtRaw(poolSize)) {
			for (int i = 0; ((i < getFiguresAtLine(poolSize)) && (availablePlants > 0)); i++) {
				for (int j = 0; ((j < SPACE_DIM.getSecond()) && (availablePlants > 0)); j++) {
					if(!plantMap.get(j).isEmpty()) {
						Iterator<Integer> itr = plantMap.get(j).iterator();
						while((itr.hasNext()) && (availablePlants > 0)) {
							pool[j + (columnNumber * SPACE_DIM.getSecond())][(itr.next()) + (i * SPACE_DIM.getFirst())] = '+';
							availablePlants -= 1;
						}
					}
				}
			}
			columnNumber += 1;
		}
		
		//Fill the remaining.
		int remainingPlants = availablePlants + (inputPlantsNumber % PLANTS_NUM);
		
		int horizontalGapIndex = poolSize - (columnNumber * SPACE_DIM.getSecond());
		int verticalGapIndex = poolSize - (getFiguresAtLine(poolSize) * SPACE_DIM.getFirst());
		
		if ((horizontalGapIndex) > (verticalGapIndex)) {
			//horizontal gap filling.
			
			//Gap insuficient!
			if (horizontalGapIndex * poolSize < remainingPlants) {
				while (remainingPlants > 0)	{
					Random ranGenerator = new Random();
					int i = ranGenerator.nextInt(poolSize);
					int j = ranGenerator.nextInt(poolSize);
					if (pool[i][j] != '+') {
						pool[i][j] = '+';
						remainingPlants -= 1;
					}
				}
			} else {
				while (remainingPlants > 0)	{
					Random ranGenerator = new Random();
					int i = 0;
					while(i < (columnNumber * SPACE_DIM.getSecond())) {
						i = ranGenerator.nextInt(poolSize);
					}
					int j = ranGenerator.nextInt(poolSize);
					if (pool[i][j] != '+') {
						pool[i][j] = '+';
						remainingPlants -= 1;
					}
				}
			}
			
		} else {
			//vertical gap filling.
			
			//Gap insuficient
			if (verticalGapIndex * poolSize < remainingPlants) {
				while (remainingPlants > 0)	{
					Random ranGenerator = new Random();
					int i = ranGenerator.nextInt(poolSize);
					int j = ranGenerator.nextInt(poolSize);
					if (pool[i][j] != '+') {
						pool[i][j] = '+';
						remainingPlants -= 1;
					}
				}
			} else {
				while (remainingPlants > 0)	{
					Random ranGenerator = new Random();
					int j = 0;
					while(j < (getFiguresAtLine(poolSize) * SPACE_DIM.getFirst())) {
						j = ranGenerator.nextInt(poolSize);
					}
					int i = ranGenerator.nextInt(poolSize);
					if (pool[i][j] != '+') {
						pool[i][j] = '+';
						remainingPlants -= 1;
					}
				}
			}
		}
	}
	/*
	//To be deleted main function is not needed in this class!
	public static void main(String args[]) {
		Character[][] pool = {
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},
				{'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'}
		};
		int inputPlantsNumber = 127; 
		int poolSize = 36;
		int lifeDuration = 45;
			
		System.out.println(isSuitableFigure(inputPlantsNumber, poolSize, lifeDuration));
		fillPool(pool, inputPlantsNumber, poolSize);
		printMatrix(pool, poolSize);
	}
	private static void printMatrix (Character[][] pool, int poolSize) {
		for(int i = 0; i < poolSize; i++) {
			for(int j = 0; j < poolSize; j++) {
				System.out.print(pool[i][j]);
			}
			System.out.println();
		}
	}
	*/
}
